package org.wmq.taskschedule.algorithm;

import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.imgproc.Imgproc;

/**
 * 图像旋转算法执行器
 * 实现AlgorithmExecutor接口，用于对图像进行旋转处理
 */
public class ImageRotationExecutor implements AlgorithmExecutor {

    private double angle; // 旋转角度（度）
    private int scale; // 缩放比例
    private boolean keepSize; // 是否保持原始大小
    private String description; // 算法描述

    /**
     * 默认构造函数，使用默认参数
     */
    public ImageRotationExecutor() {
        this.angle = 90.0;
        this.scale = 1;
        this.keepSize = true;
        this.description = "图像旋转算法 - 旋转图像到指定角度";
    }

    /**
     * 构造函数，允许自定义参数
     * 
     * @param angle 旋转角度（度）
     * @param scale 缩放比例
     */
    public ImageRotationExecutor(double angle, int scale) {
        this.angle = angle;
        this.scale = scale;
        this.keepSize = true;
        this.description = "图像旋转算法 - 旋转图像到指定角度";
    }

    /**
     * 构造函数，允许自定义所有参数
     * 
     * @param angle 旋转角度（度）
     * @param scale 缩放比例
     * @param keepSize 是否保持原始大小
     * @param description 算法描述
     */
    public ImageRotationExecutor(double angle, int scale, boolean keepSize, String description) {
        this.angle = angle;
        this.scale = scale;
        this.keepSize = keepSize;
        this.description = description;
    }

    @Override
    public Mat execute(Mat input) {
        if (input == null || input.empty()) {
            throw new IllegalArgumentException("输入图像不能为空");
        }

        // 创建输出图像
        Mat output = new Mat();

        // 计算旋转中心
        Point center = new Point(input.cols() / 2, input.rows() / 2);

        // 计算旋转矩阵
        Mat rotationMatrix = Imgproc.getRotationMatrix2D(center, angle, scale);

        // 应用旋转
        // 应用旋转
        Imgproc.warpAffine(input, output, rotationMatrix,
                keepSize ? new org.opencv.core.Size(input.cols(), input.rows()) : new org.opencv.core.Size(0, 0));

        // 释放中间资源
        rotationMatrix.release();

        return output;
    }

    // Getters and setters
    public double getAngle() {
        return angle;
    }

    public void setAngle(double angle) {
        this.angle = angle;
    }

    public int getScale() {
        return scale;
    }

    public void setScale(int scale) {
        this.scale = scale;
    }

    public boolean isKeepSize() {
        return keepSize;
    }

    public void setKeepSize(boolean keepSize) {
        this.keepSize = keepSize;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}